// 用于拼接字符串（自动插入换行）并替换到代码文件的类
function myString(dfText) {
    this.val = dfText || ''
    this.add = text => (this.val += (text || '') + '\r\n')
    this.writeTo = (strCode,tag) => {
        return strCode.replace(new RegExp(`\\@${tag},?`, 'g'), this.val.trimLeft())
    }
}
function setDtoRes(tables,ptable,str,allTables){
    if(tables.length>0){
        str.add(`            if(res.${window.$upFirst(ptable.className)}Entity != null)`)
        str.add(`            {`)
        
        tables.forEach(table =>{
            if(table.relationType == '2'){
                str.add(`                res.${window.$upFirst(table.className)}List = await _i${window.$upFirst(table.className)}BLL.GetList(new ${window.$upFirst(table.className)}Entity { ${window.$upFirst(table.field)} = res.${window.$upFirst(ptable.className)}Entity.${window.$upFirst(table.relationField)} });`)
            }
            else{
                str.add(`                res.${window.$upFirst(table.className)}Entity = await _i${window.$upFirst(table.className)}BLL.GetRelateEntity(res.${window.$upFirst(ptable.className)}Entity.${window.$upFirst(table.relationField)} );`)
            }
        })
        str.add(`            }`)

        tables.forEach(table =>{
            const ctables = allTables.filter(t=>t.relationName == table.name)
            if(ctables){
                setDtoRes(ctables,table,str,allTables)
            }
        })
    }
}

export const generatorApi = (setting,temp)=>{
    let strCode = temp;
    temp = null;

    strCode = strCode.replace('@IBLLNamespace',`using ${setting.namespace.ibll}`)
    strCode = strCode.replace('@Namespace',setting.namespace.webapi)
    strCode = strCode.replace('@ProjectName',`${setting.project.f_Name}-${setting.moduleName}`)
    strCode = strCode.replace('@CompanyName',setting.company)
    strCode = strCode.replace('@CreateUserName',setting.userInfo.f_RealName)
    strCode = strCode.replace('@Datetime',setting.createTime)
    
    
    // 构造方法处理
    var initMethod = new myString()
    let ibllName = ''
    setting.dbTable.forEach(ctable => {
        ibllName += `I${window.$upFirst(ctable.className)}BLL i${window.$upFirst(ctable.className)}BLL,`
        initMethod.add(`        private readonly I${window.$upFirst(ctable.className)}BLL _i${window.$upFirst(ctable.className)}BLL;`)
    })
    initMethod.add(`        /// <summary>`)
    initMethod.add(`        /// 构造方法`)
    initMethod.add(`        /// <summary>`)
    setting.dbTable.forEach(ctable => {
        initMethod.add(`        /// <param name="i${window.$upFirst(ctable.className)}BLL">${ctable.comment}接口</param>`)
    })
    initMethod.add(`        public @ControllerName(${ibllName.substring(0,ibllName.length-1)})`)
    initMethod.add('        {')
    setting.dbTable.forEach(ctable => {
        initMethod.add(`            _i${window.$upFirst(ctable.className)}BLL = i${window.$upFirst(ctable.className)}BLL?? throw new ArgumentNullException(nameof(i${window.$upFirst(ctable.className)}BLL));`)
    })
    initMethod.add('        }')

    strCode = initMethod.writeTo(strCode,'InitMethod')
    initMethod = null


    var getMethod = new myString()
    var addMethod = new myString()
    var updateMethod = new myString()
    var deleteMethod = new myString()

    setting.dbTable.forEach(table =>{
        if(table.type == 'main'){
            getMethod.add(`        /// <summary>`)
            getMethod.add(`        /// 获取@Des的列表数据`)
            getMethod.add(`        /// </summary>`)
            getMethod.add(`        /// <param name="queryParams">查询参数</param>`)
            getMethod.add(`        /// <returns></returns>`)
            getMethod.add(`        [HttpGet("@ApiNames")]`)
            getMethod.add(`        [ProducesResponseType(typeof(ResponseDto<IEnumerable<${table.className}Entity>>), 200)]`)
            getMethod.add(`        public async Task<IActionResult> GetList([FromQuery]${table.className}Entity queryParams)`)
            getMethod.add(`        {`)
            if(setting.qTables.length >1){
                getMethod.add(`            var list = await _i${table.className}BLL.GetRelateList(queryParams);`)
            }
            else{
                getMethod.add(`            var list = await _i${table.className}BLL.GetList(queryParams);`)
            }
            getMethod.add(`            return Success(list);`)
            getMethod.add(`        }`)

            getMethod.add(`        /// <summary>`)
            getMethod.add(`        /// 获取@Des的分页列表数据`)
            getMethod.add(`        /// </summary>`)
            getMethod.add(`        /// <param name="paginationInputDto">分页参数</param>`)
            getMethod.add(`        /// <param name="queryParams">查询参数</param>`)
            getMethod.add(`        /// <returns></returns>`)
            getMethod.add(`        [HttpGet("@ApiName/page")]`)
            getMethod.add(`        [ProducesResponseType(typeof(PaginationOutputDto<IEnumerable<${table.className}Entity>>), 200)]`)
            getMethod.add(`        public async Task<IActionResult> GetPageList([FromQuery]PaginationInputDto paginationInputDto, [FromQuery]${table.className}Entity queryParams)`)
            getMethod.add(`        {`)
            getMethod.add(`            Pagination pagination = paginationInputDto.ToObject<Pagination>();`)
            if(setting.qTables.length >1){
                getMethod.add(`            var list = await _i${table.className}BLL.GetRelatePageList(pagination,queryParams);`)
            }
            else{
                getMethod.add(`            var list = await _i${table.className}BLL.GetPageList(pagination,queryParams);`)
            }
            getMethod.add(`            var jsonData = new`)
            getMethod.add(`            {`)
            getMethod.add(`                rows = list,`)
            getMethod.add(`                pagination.total,`)
            getMethod.add(`                pagination.page,`)
            getMethod.add(`                pagination.records`)
            getMethod.add(`            };`)
            getMethod.add(`            return Success(jsonData);`)
            getMethod.add(`        }`)
            

            getMethod.add(`        /// <summary>`)
            getMethod.add(`        /// 获取表单数据`)
            getMethod.add(`        /// <summary>`)
            getMethod.add(`        /// <param name="keyValue">主键</param>`)
            getMethod.add(`        /// <returns></returns>`)
            getMethod.add(`        [HttpGet("@ApiName/{id}")]`)
            
            if(setting.dbTable.length > 1){
                getMethod.add(`        [ProducesResponseType(typeof(ResponseDto<${window.$upFirst(setting.name)}Dto>), 200)]`)
                getMethod.add(`        public async Task<IActionResult>GetForm(@PkType id)`)
                getMethod.add(`        {`)
                getMethod.add(`            var res = new ${window.$upFirst(setting.name)}Dto();`)
                getMethod.add(`            res.${window.$upFirst(`${table.className}Entity`)} = await _i${table.className}BLL.GetEntity(id);`)
                const cdbTables = setting.dbTable.filter(t=>t.relationName == table.name)
                setDtoRes(cdbTables,table,getMethod, setting.dbTable)
                getMethod.add(`            return Success(res);`)
                getMethod.add(`        }`)
            }
            else{
                getMethod.add(`        [ProducesResponseType(typeof(ResponseDto<${window.$upFirst(table.className)}Entity>), 200)]`)
                getMethod.add(`        public async Task<IActionResult>GetForm(@PkType id)`)
                getMethod.add(`        {`)
                getMethod.add(`            var data = await _i${table.className}BLL.GetEntity(id);`)
                getMethod.add(`            return Success(data);`)
                getMethod.add(`        }`)
            }

            addMethod.add(`        /// <summary>`)
            addMethod.add(`        /// 新增表单数据`)
            addMethod.add(`        /// <summary>`)
            addMethod.add(`        /// <param name="dto">表单数据</param>`)
            addMethod.add(`        /// <returns></returns>`)
            addMethod.add(`        [HttpPost("@ApiName")]`)
            addMethod.add(`        [ProducesResponseType(typeof(ResponseDto<${table.className}Entity>), 200)]`)
            if(setting.dbTable.length > 1){
                addMethod.add(`        public async Task<IActionResult>AddForm(${window.$upFirst(setting.name)}Dto dto)`)
                addMethod.add(`        {`)
                addMethod.add(`            await _i${table.className}BLL.SaveAll(null,dto);`)
                addMethod.add(`            return Success("新增成功！", dto.${table.className}Entity);`)
                addMethod.add(`        }`)
            }
            else{
                addMethod.add(`        public async Task<IActionResult>AddForm(${table.className}Entity dto)`)
                addMethod.add(`        {`)
                addMethod.add(`            await _i${table.className}BLL.SaveEntity(null,dto);`)
                addMethod.add(`            return Success("新增成功！",dto);`)
                addMethod.add(`        }`)
            }


            updateMethod.add(`        /// <summary>`)
            updateMethod.add(`        /// 更新数据`)
            updateMethod.add(`        /// <summary>`)
            updateMethod.add(`        /// <param name="dto">数据集合</param>`)
            updateMethod.add(`        /// <returns></returns>`)
            updateMethod.add(`        [HttpPut("@ApiName/{id}")]`)
            updateMethod.add(`        [ProducesResponseType(typeof(ResponseDto), 200)]`)

            if(setting.dbTable.length > 1){
                updateMethod.add(`        public async Task<IActionResult>UpdateForm(${table.columns.find(t=>t.isPrimary).csType} id,${window.$upFirst(setting.name)}Dto dto)`)
                updateMethod.add(`        {`)
                updateMethod.add(`            await _i${table.className}BLL.SaveAll(id,dto);`)
                updateMethod.add(`            return Success("更新成功！");`)
                updateMethod.add(`        }`)
            }
            else{
                updateMethod.add(`        public async Task<IActionResult>UpdateForm(${table.columns.find(t=>t.isPrimary).csType} id,${table.className}Entity dto)`)
                updateMethod.add(`        {`)
                updateMethod.add(`            await _i${table.className}BLL.SaveEntity(id,dto);`)
                updateMethod.add(`            return Success("更新成功！");`)
                updateMethod.add(`        }`)
            }



            deleteMethod.add(`        /// <summary>`)
            deleteMethod.add(`        /// 删除${table.comment}${table.name}数据`)
            deleteMethod.add(`        /// <summary>`)
            deleteMethod.add(`        /// <param name="id">主键</param>`)
            deleteMethod.add(`        /// <returns></returns>`)
            deleteMethod.add(`        [HttpDelete("@ApiName/{id}")]`)
            deleteMethod.add(`        [ProducesResponseType(typeof(ResponseDto), 200)]`)
            deleteMethod.add(`        public async Task<IActionResult>DeleteForm(${table.columns.find(t=>t.isPrimary).csType} id)`)
            deleteMethod.add(`        {`)
            if(setting.dbTable.length > 1){
                deleteMethod.add(`            await _i${table.className}BLL.DeleteAll(id);`)
            }
            else{
                deleteMethod.add(`            await _i${table.className}BLL.Delete(id);`)
            }

            deleteMethod.add(`            return Success("删除成功！");`)
            deleteMethod.add(`        }`)
        }
        else{
            getMethod.add(`        /// <summary>`)
            getMethod.add(`        /// 获取${table.comment}${table.name}的列表数据`)
            getMethod.add(`        /// </summary>`)
            getMethod.add(`        /// <param name="queryParams">查询参数</param>`)
            getMethod.add(`        /// <returns></returns>`)
            getMethod.add(`        [HttpGet("@ApiName/${window.$lowerFirst(table.className)}s")]`)
            getMethod.add(`        [ProducesResponseType(typeof(ResponseDto<IEnumerable<${table.className}Entity>>), 200)]`)
            getMethod.add(`        public async Task<IActionResult> Get${table.className}List([FromQuery]${table.className}Entity queryParams)`)
            getMethod.add(`        {`)
            getMethod.add(`            var list = await _i${table.className}BLL.GetList(queryParams);`)
            getMethod.add(`            return Success(list);`)
            getMethod.add(`        }`)

            getMethod.add(`        /// <summary>`)
            getMethod.add(`        /// 获取${table.comment}${table.name}的分页列表数据`)
            getMethod.add(`        /// </summary>`)
            getMethod.add(`        /// <param name="paginationInputDto">分页参数</param>`)
            getMethod.add(`        /// <param name="queryParams">查询参数</param>`)
            getMethod.add(`        /// <returns></returns>`)
            getMethod.add(`        [HttpGet("@ApiName/${window.$lowerFirst(table.className)}/page")]`)
            getMethod.add(`        [ProducesResponseType(typeof(PaginationOutputDto<IEnumerable<${table.className}Entity>>), 200)]`)
            getMethod.add(`        public async Task<IActionResult> Get${table.className}PageList([FromQuery]PaginationInputDto paginationInputDto, [FromQuery]${table.className}Entity queryParams)`)
            getMethod.add(`        {`)
            getMethod.add(`            Pagination pagination = paginationInputDto.ToObject<Pagination>();`)
            getMethod.add(`            var list = await _i${table.className}BLL.GetPageList(pagination,queryParams);`)
            getMethod.add(`            var jsonData = new`)
            getMethod.add(`            {`)
            getMethod.add(`                rows = list,`)
            getMethod.add(`                pagination.total,`)
            getMethod.add(`                pagination.page,`)
            getMethod.add(`                pagination.records`)
            getMethod.add(`            };`)
            getMethod.add(`            return Success(jsonData);`)
            getMethod.add(`        }`)
        }

        getMethod.add(`        /// <summary>`)
        getMethod.add(`        /// 获取${table.comment}${table.name}数据`)
        getMethod.add(`        /// <summary>`)
        getMethod.add(`        /// <param name="id">主键</param>`)
        getMethod.add(`        /// <returns></returns>`)
        getMethod.add(`        [HttpGet("@ApiName/${window.$lowerFirst(table.className)}/{id}")]`)
        getMethod.add(`        [ProducesResponseType(typeof(ResponseDto<${window.$upFirst(table.className)}Entity>), 200)]`)
        getMethod.add(`        public async Task<IActionResult>Get${table.className}Entity(${table.columns.find(t=>t.isPrimary).csType} id)`)
        getMethod.add(`        {`)
        getMethod.add(`            var data = await _i${table.className}BLL.GetEntity(id);`)
        getMethod.add(`            return Success(data);`)
        getMethod.add(`        }`)

        addMethod.add(`        /// <summary>`)
        addMethod.add(`        /// 新增${table.comment}${table.name}数据`)
        addMethod.add(`        /// <summary>`)
        addMethod.add(`        /// <param name="entity">表单数据</param>`)
        addMethod.add(`        /// <returns></returns>`)
        addMethod.add(`        [HttpPost("@ApiName/${window.$lowerFirst(table.className)}")]`)
        addMethod.add(`        [ProducesResponseType(typeof(ResponseDto<${table.className}Entity>), 200)]`)
        addMethod.add(`        public async Task<IActionResult>Add${table.className}(${table.className}Entity entity)`)
        addMethod.add(`        {`)
        addMethod.add(`            await _i${table.className}BLL.SaveEntity(null,entity);`)
        addMethod.add(`            return Success("新增成功！", entity);`)
        addMethod.add(`        }`)

        updateMethod.add(`        /// <summary>`)
        updateMethod.add(`        /// 更新${table.comment}${table.name}数据`)
        updateMethod.add(`        /// <summary>`)
        updateMethod.add(`        /// <param name="entity">表单数据</param>`)
        updateMethod.add(`        /// <returns></returns>`)
        updateMethod.add(`        [HttpPut("@ApiName/${window.$lowerFirst(table.className)}/{id}")]`)
        updateMethod.add(`        [ProducesResponseType(typeof(ResponseDto), 200)]`)
        updateMethod.add(`        public async Task<IActionResult>Update${table.className}(${table.columns.find(t=>t.isPrimary).csType} id,${table.className}Entity entity)`)
        updateMethod.add(`        {`)
        updateMethod.add(`            await _i${table.className}BLL.SaveEntity(id,entity);`)
        updateMethod.add(`            return Success("更新成功！");`)
        updateMethod.add(`        }`)

        deleteMethod.add(`        /// <summary>`)
        deleteMethod.add(`        /// 删除${table.comment}${table.name}数据`)
        deleteMethod.add(`        /// <summary>`)
        deleteMethod.add(`        /// <param name="id">主键</param>`)
        deleteMethod.add(`        /// <returns></returns>`)
        deleteMethod.add(`        [HttpDelete("@ApiName/${window.$lowerFirst(table.className)}/{id}")]`)
        deleteMethod.add(`        [ProducesResponseType(typeof(ResponseDto), 200)]`)
        deleteMethod.add(`        public async Task<IActionResult>Delete${table.className}(${table.columns.find(t=>t.isPrimary).csType} id)`)
        deleteMethod.add(`        {`)
        deleteMethod.add(`            await _i${table.className}BLL.Delete(id);`)
        deleteMethod.add(`            return Success("删除成功！");`)
        deleteMethod.add(`        }`)

    })

    strCode = getMethod.writeTo(strCode,'GetMethod')
    getMethod = null

    strCode = addMethod.writeTo(strCode,'AddMethod')
    addMethod = null

    strCode = updateMethod.writeTo(strCode,'UpdateMethod')
    updateMethod = null

    strCode = deleteMethod.writeTo(strCode,'DeleteMethod')
    deleteMethod = null

    
    


    let pkCsType = setting.dbTable.find(t=>t.type == 'main').columns.find(t=>t.isPrimary).csType

    strCode = strCode.replace(/@PkType/g,`${pkCsType}`)
    strCode = strCode.replace(/@Des/g,`${setting.des}`)
    strCode = strCode.replace(/@ControllerName/g,window.$upFirst(`${setting.name}Controller`))
    strCode = strCode.replace(/@ApiName/g,`${window.$lowerFirst(setting.moduleId)}/${window.$lowerFirst(setting.name)}`)
    return strCode;
}